home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QRZ! Ham Radio 8
/
QRZ Ham Radio Callsign Database - Volume 8.iso
/
pc
/
files
/
t_unix
/
j109lxa4.tar
/
at.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-04
|
8KB
|
383 lines
/* Timed execution routine. Starts a timer and executes a sequence
* of commands when expired.
*
* Added by IW0CNB - Feb 1992
* 'at mm' format added by WG7J - 920805
*
* Added by WA7TAS Oct 1992:
*
* Repeating AT command
* 'at k' command
*
*/
#include <stdio.h>
#include <time.h>
#ifdef MSDOS
#include <dos.h>
#endif
#include "global.h"
#include "timer.h"
#include "cmdparse.h"
#include "socket.h"
#ifdef UNIX
#define mktime j_mktime
#ifdef __cplusplus
extern "C" {
#endif
extern time_t mktime __ARGS((struct tm *));
#ifdef __cplusplus
}
#endif
#endif
static void atcmd __ARGS((char *command));
static void atproc __ARGS((int i,void *p1,void *p2));
/* List of events; We keep note of all timer processes generated by the
* at command.
*/
struct at_list {
struct at_list *next; /* Linked-list pointer */
struct timer *at_timer;
char recur[10]; /* used in recursive 'at' commands*/
unsigned int id; /* numerical 'id' of this 'at' */
};
#define NULLATLIST (struct at_list *)0
static struct at_list *Head_loe = NULLATLIST; /* Head of List Of Events */
static int id=1; /* next 'at' assigned gets this number */
int
#ifdef PROTOTYPES
doat(int argc,char **argv,void *p)
#else
doat(argc,argv,p)
int argc;
char *argv[];
void *p;
#endif
{
struct date *exp_date;
struct time *exp_time;
struct timer *t;
char *cp;
unsigned int tid;
int i,notf;
time_t nowtime;
unsigned long time1;
struct tm tm;
extern struct timer *Timers;
struct at_list *loe,*pp; /* List of events */
char *Errmsg = "Usage:\nat yymmddhhmm <cmd>\nat hhmm <cmd>\nat mm <cmd>\nat now+hhmm <cmd>\nat k <id num> <id num> ...\n";
if(argc < 2){ /* Print list of pending at commands */
tputs("List of events:\n");
for(t = Timers;t != NULLTIMER;t = t->next){
if(t->func == (void (*)__ARGS((void*)))atcmd){
loe=Head_loe;
while(loe!=NULLATLIST) {
if(loe->at_timer == t) break;
loe=loe->next;
}
time(&nowtime);
nowtime = (time_t)(read_timer(t) / 1000L + (unsigned long)nowtime);
cp = ctime(&nowtime);
rip(cp);
#if 0
tprintf("At: %s - ID: %5u - Command: %s\n",cp,loe->id,t->arg);
#endif
/* KF8NH: account for ID hidden at start of command */
tprintf("At: %s - ID: %5u - Command: %s\n",cp,loe->id,(char*)t->arg + sizeof loe->id);
}
}
return 0;
}
if(argc < 3){
tputs(Errmsg);
return 0;
}
if(argv[1][0]=='k') {
i=2;
while(i<argc) {
tid=atoi(argv[i]);
if(strlen(argv[i])>5 || tid==0 || atol(argv[i])>65535) {
tprintf("Invalid ID #.\n");
return 0;
}
loe=Head_loe;
notf=1;
#ifdef __GNUC__
pp = 0; /* silence warning */
#endif
while(loe!=NULLATLIST) {
if(loe->id==tid) {
stop_timer(loe->at_timer);
free(loe->at_timer->arg);
free(loe->at_timer);
if(loe == Head_loe) {
Head_loe=loe->next;
}
else {
pp->next=loe->next;
}
free(loe);
tprintf("at id: %u--Killed.\n",tid);
notf=0;
break;
}
pp=loe;
loe=loe->next;
}
if(notf) tprintf(" ID %u not found.\n",tid);
i++;
}
return 0;
}
exp_date = (struct date *)mallocw(sizeof(struct date));
exp_time = (struct time *)mallocw(sizeof(struct time));
cp=mallocw(5);
switch(strlen(argv[1])){
case 10: /* Full date and time given */
cp[0]=argv[1][0];
cp[1]=argv[1][1];
cp[2]='\0';
exp_date->da_year = 1900 + atoi(cp);
if(exp_date->da_year > 1999) goto error;
cp[0]=argv[1][2];
cp[1]=argv[1][3];
cp[2]='\0';
exp_date->da_mon = (char)atoi(cp);
if(exp_date->da_mon > 12) goto error;
cp[0]=argv[1][4];
cp[1]=argv[1][5];
cp[2]='\0';
exp_date->da_day = (char)atoi(cp);
if(exp_date->da_day > 31) goto error;
cp[0]=argv[1][6];
cp[1]=argv[1][7];
cp[2]='\0';
exp_time->ti_hour = (char)atoi(cp);
if(exp_time->ti_hour > 23) goto error;
cp[0]=argv[1][8];
cp[1]=argv[1][9];
cp[2]='\0';
exp_time->ti_min = (char)atoi(cp);
if(exp_time->ti_min > 59) goto error;
exp_time->ti_sec = 0;
exp_time->ti_hund = 0;
time(&nowtime);
time1 = (unsigned long)dostounix(exp_date,exp_time);
if(time1 < (unsigned long)nowtime) goto error;
break;
case 4: /* Only time given, so apply current date */
getdate(exp_date);
cp[0]=argv[1][0];
cp[1]=argv[1][1];
cp[2]='\0';
exp_time->ti_hour = (char)atoi(cp);
if(exp_time->ti_hour > 23) goto error;
cp[0]=argv[1][2];
cp[1]=argv[1][3];
cp[2]='\0';
exp_time->ti_min = (char)atoi(cp);
if(exp_time->ti_min > 59) goto error;
exp_time->ti_sec = 0;
exp_time->ti_hund = 0;
time(&nowtime);
time1 = (unsigned long)dostounix(exp_date,exp_time);
if(time1 <= (unsigned long)nowtime){ /* Requested time has passed */
time1 += 86400L; /* So book him for tomorrow */
}
break;
case 2: /* Only minutes given, so apply current time & date - WG7J */
tm.tm_min = (char)atoi(argv[1]);
if(tm.tm_min > 59) goto error;
/* get today's date */
getdate(exp_date);
tm.tm_year = exp_date->da_year - 1900;
tm.tm_mday = exp_date->da_day;
tm.tm_mon = exp_date->da_mon - 1;
/* get current time */
gettime(exp_time);
tm.tm_hour = exp_time->ti_hour;
/* if we're already past the minute, do it next hour ! */
if(exp_time->ti_min > tm.tm_min)
tm.tm_hour++;
/* now adjust this for day boundaries, etc. */
tm.tm_sec = 0;
tm.tm_isdst = 0;
time1 = mktime(&tm);
time(&nowtime);
break;
case 8: /* now+hhmm given */
strncpy(cp,argv[1],4);
cp[4]='\0';
if(strcmp(cp,"now+") != 0) goto error;
cp[0]=argv[1][4];
cp[1]=argv[1][5];
cp[2]='\0';
time1=(unsigned long)atoi(cp)*3600L;
cp[0]=argv[1][6];
cp[1]=argv[1][7];
cp[2]='\0';
time1+=(unsigned long)atoi(cp)*60L;
time(&nowtime);
time1+=(unsigned long)nowtime;
break;
default:
error: tprintf(Errmsg);
free(exp_date);
free(exp_time);
free(cp);
return 0;
} /* switch */
free(cp);
free(exp_time);
free(exp_date);
t=(struct timer *)mallocw(sizeof(struct timer));
set_timer(t,(int32)(time1 - (unsigned long)nowtime) * 1000L);
t->state=TIMER_RUN;
t->func=(void (*)__ARGS((void*)))atcmd;
/* Add the new timer to the head of List Of Events */
loe=(struct at_list *)mallocw(sizeof(struct at_list));
loe->at_timer=t;
/*
* if timer is recursive, set at_list->recur
*/
loe->recur[0]=0;
if(argv[2][strlen(argv[2])-1] == '+') strcpy(loe->recur,argv[1]);
/*
* an id of 0 is invalid
*/
if(id==0) id=1;
loe->id=id++;
loe->next=Head_loe;
Head_loe=loe;
/* KF8NH: save ID as well for atproc() (q.v.) */
/* (excessive use of sizeof() so this works for both of us...) */
t->arg = (char *) mallocw(strlen(argv[2]) + sizeof loe->id + 2);
memcpy(t->arg, &loe->id, sizeof loe->id);
strcpy(((char *) t->arg) + sizeof loe->id, argv[2]);
start_timer(t);
return 0;
}
/* Process that actually handles 'at' execution */
void
atproc(int i,void *p1,void *p2) {
extern struct cmds far Cmds[];
char *command;
struct at_list *loe, *p;
int recur;
char *cmd;
command = (char *)p1;
cmd = malloc(strlen(command) + 20);
log(-1,"AT command: %s",command);
/* Free up memory for expired at commands */
p=Head_loe;
loe=Head_loe;
cmd[0] = '\0';
while(loe != NULLATLIST){
if (loe->id == i && loe->at_timer->state == TIMER_EXPIRE) {
strcpy(cmd,"at ");
strcat(cmd,loe->recur);
free(loe->at_timer); /* Free timer */
if(loe == Head_loe){
Head_loe=loe->next;
p=loe->next;
free(loe);
loe=p;
p=Head_loe;
} else {
p->next=loe->next;
free(loe);
loe=p->next;
}
break;
}
if(loe != Head_loe) p=p->next;
loe=loe->next;
}
if (!*cmd)
where_outta_here(1);
if(command[strlen(command)-1] == '+') {
strcat(cmd," \"");
strcat(cmd,command);
strcat(cmd,"\"");
recur=1;
command[strlen(command)-1]=0;
}
else recur=0;
cmdparse(Cmds,command,NULL); /* Go with requested command */
if(recur) {
cmdparse(Cmds,cmd,NULL);
}
free(cmd);
free(p2); /* correct... */
}
/* Function to be called on timer expiration to execute a command */
void
atcmd(command)
char *command;
{
unsigned int id; /* KF8NH: extracted for atproc check */
/* WARNING: the above must be precisely the same size as Head_loe->id */
memcpy(&id, command, sizeof id);
newproc("AT handler", 1024, atproc, (int)id, (void *) (command + sizeof id),
command, 0);
}